package com.srwl.mytx.utils;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.Editable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.ColorInt;

import com.srwl.easeui.utils.EmojiManager;
import com.srwl.mytx.R;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * CSDN_LQR
 * 图文混排工具
 */
public class MoonUtils {
    private static final float DEF_SCALE = 0.6f;
    private static final float SMALL_SCALE = 0.6F;

    /**
     * 具体类型的view设置内容
     *
     * @param textView
     * @param mSpannableString
     */
    private static void viewSetText(View textView, SpannableString mSpannableString) {
        if (textView instanceof TextView) {
            TextView tv = (TextView) textView;
            tv.setText(mSpannableString);
        }
    }

    private static SpannableString replaceEmoticons(Context context, String value, float scale, int align) {
        if (TextUtils.isEmpty(value)) {
            value = "";
        }

        final char[] chars = value.toCharArray();
        final SpannableStringBuilder ssb = new SpannableStringBuilder(value);

        int codePoint;
        boolean isSurrogatePair;
        for (int i = 0; i < chars.length; i++) {
            if (Character.isHighSurrogate(chars[i])) {
                continue;
            } else if (Character.isLowSurrogate(chars[i])) {
                if (i > 0 && Character.isSurrogatePair(chars[i - 1], chars[i])) {
                    codePoint = Character.toCodePoint(chars[i - 1], chars[i]);
                    isSurrogatePair = true;
                } else {
                    continue;
                }
            } else {
                codePoint = (int) chars[i];
                isSurrogatePair = false;
            }

            Integer emojiResourceId = EmojiManager.getEmojiResourceId(codePoint);
            if (emojiResourceId != null) {
                Drawable d = getEmotDrawable(context, emojiResourceId, scale);

                ImageSpan span = new ImageSpan(d, align);
                ssb.setSpan(span, isSurrogatePair ? i - 1 : i, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

            }
        }

        return SpannableString.valueOf(ssb);
    }

    /**
     * 替换 表情 并高亮显示关键词
     *
     * @param context
     * @param value
     * @param scale
     * @param align
     * @param highlightKeyWork
     * @param highlightColorSourId
     * @return
     */
    public static SpannableString replaceEmoticonsAndHighlight(Context context, String value, float scale, int align, String highlightKeyWork, @ColorInt Integer highlightColorSourId) {
        if (TextUtils.isEmpty(value)) {
            value = "";
        }

        final char[] chars = value.toCharArray();
        final SpannableStringBuilder builder = new SpannableStringBuilder(value);

        int codePoint;
        boolean isSurrogatePair;
        for (int i = 0; i < chars.length; i++) {
            if (Character.isHighSurrogate(chars[i])) {
                continue;
            } else if (Character.isLowSurrogate(chars[i])) {
                if (i > 0 && Character.isSurrogatePair(chars[i - 1], chars[i])) {
                    codePoint = Character.toCodePoint(chars[i - 1], chars[i]);
                    isSurrogatePair = true;
                } else {
                    continue;
                }
            } else {
                codePoint = (int) chars[i];
                isSurrogatePair = false;
            }

            Integer emojiResourceId = EmojiManager.getEmojiResourceId(codePoint);
            if (emojiResourceId != null) {
                Drawable d = getEmotDrawable(context, emojiResourceId, scale);

                ImageSpan span = new ImageSpan(d, align);
                builder.setSpan(span, isSurrogatePair ? i - 1 : i, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

            }
        }
        if (!TextUtils.isEmpty(highlightKeyWork) && highlightColorSourId != null) {
            ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(highlightColorSourId);
            Pattern p = Pattern.compile(highlightKeyWork);
            Matcher m = p.matcher(value);
            while (m.find()) {
                int start = m.start();
                int end = m.end();
                builder.setSpan(foregroundColorSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        return SpannableString.valueOf(builder);
    }

    private static Pattern mATagPattern = Pattern.compile("<a.*?>.*?</a>");

    public static SpannableString makeSpannableStringTags(Context context, String value, float scale, int align) {
        return makeSpannableStringTags(context, value, scale, align, true);
    }

    public static SpannableString makeSpannableStringTags(Context context, String value, float scale, int align, boolean bTagClickable) {
        ArrayList<ATagSpan> tagSpans = new ArrayList<ATagSpan>();
        if (TextUtils.isEmpty(value)) {
            value = "";
        }
        //a标签需要替换原始文本,放在moonutil类中
        Matcher aTagMatcher = mATagPattern.matcher(value);

        int start = 0;
        int end = 0;
        while (aTagMatcher.find()) {
            start = aTagMatcher.start();
            end = aTagMatcher.end();
            String atagString = value.substring(start, end);
            ATagSpan tagSpan = getTagSpan(atagString);
            value = value.substring(0, start) + tagSpan.getTag() + value.substring(end);
            tagSpan.setRange(start, start + tagSpan.getTag().length());
            tagSpans.add(tagSpan);
            aTagMatcher = mATagPattern.matcher(value);
        }


        final char[] chars = value.toCharArray();
        final SpannableStringBuilder ssb = new SpannableStringBuilder(value);

        int codePoint;
        boolean isSurrogatePair;
        for (int i = 0; i < chars.length; i++) {
            if (Character.isHighSurrogate(chars[i])) {
                continue;
            } else if (Character.isLowSurrogate(chars[i])) {
                if (i > 0 && Character.isSurrogatePair(chars[i - 1], chars[i])) {
                    codePoint = Character.toCodePoint(chars[i - 1], chars[i]);
                    isSurrogatePair = true;
                } else {
                    continue;
                }
            } else {
                codePoint = (int) chars[i];
                isSurrogatePair = false;
            }

            Integer emojiResourceId = EmojiManager.getEmojiResourceId(codePoint);
            if (emojiResourceId != null) {
                Drawable d = getEmotDrawable(context, emojiResourceId, scale);
                ImageSpan span = new ImageSpan(d, align);
                ssb.setSpan(span, isSurrogatePair ? i - 1 : i, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

            }
        }

        return SpannableString.valueOf(ssb);
    }

    /**
     * 识别表情
     * 替换文本中的表情
     */
    public static void identifyFaceExpression(Context context,
                                              View textView, String value) {
        identifyFaceExpression(context, textView, value, ImageSpan.ALIGN_BOTTOM, DEF_SCALE);
    }

    /**
     * 识别表情和标签（如：只需显示a标签对应的文本）
     */
    public static void identifyFaceExpressionAndATags(Context context,
                                                      View textView, String value, float scale) {
        SpannableString mSpannableString = makeSpannableStringTags(context, value, scale, ImageSpan.ALIGN_BOTTOM);
        viewSetText(textView, mSpannableString);
    }

    /**
     * 识别表情，可设置缩放大小
     */
    public static void identifyFaceExpression(Context context,
                                              View textView, String value, int align, float scale) {
        SpannableString mSpannableString = replaceEmoticons(context, value, scale, align);
        viewSetText(textView, mSpannableString);
    }

    /**
     * 识别表情和标签（如：只需显示a标签对应的文本），可设置缩放大小
     */
    public static void identifyFaceExpressionAndTags(Context context,
                                                     View textView, String value, int align, float scale) {
        SpannableString mSpannableString = makeSpannableStringTags(context, value, scale, align, false);
        viewSetText(textView, mSpannableString);
    }

    /**
     * EditText用来转换表情文字的方法，如果没有使用EmoticonPickerView的attachEditText方法，则需要开发人员手动调用方法来又识别EditText中的表情
     */
    public static void replaceEmoticons(Context context, Editable editable, int start, int count) {
        if (count <= 0 || editable.length() < start + count)
            return;

        CharSequence s = editable.subSequence(start, start + count);

        final char[] chars = s.toString().toCharArray();

        int codePoint;
        boolean isSurrogatePair;
        for (int i = 0; i < chars.length; i++) {
            if (Character.isHighSurrogate(chars[i])) {
                continue;
            } else if (Character.isLowSurrogate(chars[i])) {
                if (i > 0 && Character.isSurrogatePair(chars[i - 1], chars[i])) {
                    codePoint = Character.toCodePoint(chars[i - 1], chars[i]);
                    isSurrogatePair = true;
                } else {
                    continue;
                }
            } else {
                codePoint = (int) chars[i];
                isSurrogatePair = false;
            }

            Integer emojiResourceId = EmojiManager.getEmojiResourceId(codePoint);
            if (emojiResourceId != null) {
                //  Drawable d = getEmotDrawable(context, codePoint, SMALL_SCALE);

                ImageSpan span = new ImageSpan(context, emojiResourceId, ImageSpan.ALIGN_BOTTOM);
                editable.setSpan(span, isSurrogatePair ? i - 1 : i, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

            }
        }
    }

    private static Drawable getEmotDrawable(Context context, int emojiResourceId, float scale) {
        Drawable drawable = context.getResources().getDrawable(emojiResourceId);
        if (drawable != null) {
            int width = (int) (drawable.getIntrinsicWidth() * scale);
            int height = (int) (drawable.getIntrinsicHeight() * scale);
            drawable.setBounds(0, 0, width, height);
        }
        return drawable;
    }

    private static ATagSpan getTagSpan(String text) {
        String href = null;
        String tag = null;
        if (text.toLowerCase().contains("href")) {
            int start = text.indexOf("\"");
            int end = text.indexOf("\"", start + 1);
            if (end > start)
                href = text.substring(start + 1, end);
        }
        int start = text.indexOf(">");
        int end = text.indexOf("<", start);
        if (end > start)
            tag = text.substring(start + 1, end);
        return new ATagSpan(tag, href);

    }

    private static class ATagSpan extends ClickableSpan {
        private int start;
        private int end;
        private String mUrl;
        private String tag;

        ATagSpan(String tag, String url) {
            this.tag = tag;
            this.mUrl = url;
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setUnderlineText(true);
        }

        public String getTag() {
            return tag;
        }

        public void setRange(int start, int end) {
            this.start = start;
            this.end = end;
        }

        @Override
        public void onClick(View widget) {
            try {
                if (TextUtils.isEmpty(mUrl))
                    return;
                Uri uri = Uri.parse(mUrl);
                String scheme = uri.getScheme();
                if (TextUtils.isEmpty(scheme)) {
                    mUrl = "http://" + mUrl;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    public static SpannableString getSpannableString(Context context, String fansString) {
        SpannableStringBuilder ssb = new SpannableStringBuilder(fansString);
        char[] charArray = fansString.toCharArray();
        int align = fansString.contains("万") ? ImageSpan.ALIGN_BASELINE : ImageSpan.ALIGN_BOTTOM;
        for (int i = 0, charArrayLength = charArray.length; i < charArrayLength; i++) {
            char c = charArray[i];
            ImageSpan imageSpan = getImageSpan(c, context, 0.4f, align);
            if (imageSpan != null) {
                ssb.setSpan(imageSpan, i, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        return SpannableString.valueOf(ssb);
    }

    private static ImageSpan getImageSpan(char c, Context context, float scale, int align) {
        Drawable drawable = null;
//        if (c == '0') {
//            drawable = context.getResources().getDrawable(R.drawable.tx_num_0);
//        } else if (c == '1') {
//            drawable = context.getResources().getDrawable(R.drawable.tx_num_1);
//        } else if (c == '2') {
//            drawable = context.getResources().getDrawable(R.drawable.tx_num_2);
//        } else if (c == '3') {
//            drawable = context.getResources().getDrawable(R.drawable.tx_num_3);
//        } else if (c == '4') {
//            drawable = context.getResources().getDrawable(R.drawable.tx_num_4);
//        } else if (c == '5') {
//            drawable = context.getResources().getDrawable(R.drawable.tx_num_5);
//        } else if (c == '6') {
//            drawable = context.getResources().getDrawable(R.drawable.tx_num_6);
//        } else if (c == '7') {
//            drawable = context.getResources().getDrawable(R.drawable.tx_num_7);
//        } else if (c == '8') {
//            drawable = context.getResources().getDrawable(R.drawable.tx_num_8);
//        } else if (c == '9') {
//            drawable = context.getResources().getDrawable(R.drawable.tx_num_9);
//        } else if (c == '.') {
//            drawable = context.getResources().getDrawable(R.drawable.tx_num_dot_1);
//        }

        if (c == '0') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_zero);
        } else if (c == '1') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_one);
        } else if (c == '2') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_two);
        } else if (c == '3') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_three);
        } else if (c == '4') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_four);
        } else if (c == '5') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_five);
        } else if (c == '6') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_six);
        } else if (c == '7') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_seven);
        } else if (c == '8') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_eight);
        } else if (c == '9') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_nine);
        } else if (c == '.') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_dot_1);
        }
        if (drawable != null) {
            int width = (int) (drawable.getIntrinsicWidth() * scale);
            int height = (int) (drawable.getIntrinsicHeight() * scale);
            drawable.setBounds(0, 0, width, height);
            return new ImageSpan(drawable, align);
        }
        return null;
    }

    public static SpannableString getSpannableString_red(Context context, String fansString) {
        SpannableStringBuilder ssb = new SpannableStringBuilder(fansString);
        char[] charArray = fansString.toCharArray();
        int align = fansString.contains("万") ? ImageSpan.ALIGN_BASELINE : ImageSpan.ALIGN_BOTTOM;
        for (int i = 0, charArrayLength = charArray.length; i < charArrayLength; i++) {
            char c = charArray[i];
            ImageSpan imageSpan = getImageSpan_red(c, context, 0.4f, align);
            if (imageSpan != null) {
                ssb.setSpan(imageSpan, i, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        return SpannableString.valueOf(ssb);
    }

    private static ImageSpan getImageSpan_red(char c, Context context, float scale, int algn) {
        Drawable drawable = null;

        if (c == '0') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_zero_red);
        } else if (c == '1') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_one_red);
        } else if (c == '2') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_two_red);
        } else if (c == '3') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_three_red);
        } else if (c == '4') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_four_red);
        } else if (c == '5') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_five_red);
        } else if (c == '6') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_six_red);
        } else if (c == '7') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_seven_red);
        } else if (c == '8') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_eight_red);
        } else if (c == '9') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_nine_red);
        } else if (c == '.') {
            drawable = context.getResources().getDrawable(R.drawable.tx_num_dot_red);
        }
        if (drawable != null) {
            int width = (int) (drawable.getIntrinsicWidth() * scale);
            int height = (int) (drawable.getIntrinsicHeight() * scale);
            drawable.setBounds(0, 0, width, height);
            return new ImageSpan(drawable, algn);
        }
        return null;
    }

}
